<?php
/**
 * Created by PhpStorm.
 * User: 牛赞赞
 * Date: 2021/4/26
 * Time: 9:44
 */

namespace App\Controller;

use App\Game\Core\Djs;
use App\Model\GrandMatchRecord;
use App\Model\MemberCoupon;
use App\Model\User;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use App\Model\GameLevel;
use Hyperf\Contract\ConfigInterface;

class GrandMatchController extends AbstractController
{
    /**
     * @Inject
     * @var ConfigInterface
     */
    protected $config;

    /**
     * 大奖赛大厅胜局和奖励配置
     */
    public function hall()
    {
        $res = GameLevel::getAll();
        if ($res['code']) {
            return $this->output(400, $res['msg']);
        }
        $data = array_group_by($res['data'], 'level');
        $res = [];
        foreach ($data as $k => $v) {
            if (count($v) > 1) {
                array_multisort(array_column($v, 'chance_per'), SORT_ASC, $v);
                array_push($res, $v[0]);
            } else {
                array_push($res, $v[0]);
            }
        }
        return $this->output(1, 'OK！', $res);

    }

    /**
     * 跑马灯数据
     */
    public function hot()
    {
        $redis = redis();
        $game_conf = config('game');
        $key = $game_conf['djs_run_data'];
        if ($redis->exists($key)) {
            $num = json_decode($redis->get($key), true);
        } else {
            $num = 50000;
        }
        if (($num < 70500) && ($num > 30500)) {
            $rand = rand(-500, 500);
            $num += $rand;
        } elseif ($num < 30500) {
            $rand = rand(-500, 500);
            $num += $rand;
        } elseif ($num > 70500) {
            $rand = rand(-500, 500);
            $num += $rand;
        }
        $redis->set($key, $num, expire_today());
        return $this->output(1, 'success', ['total' => $num]);
    }

    public function playTimes()
    {
        $account = $this->request->post('account');
        $playerInfo = Djs::getDjsPlayerData($account);
        if (empty($playerInfo)) {
            return $this->output(1, 'success', ['turn' => 1, 'stage' => 1, 'status' => 1, 'start_time' => '', 'alive' => 0]);
        }
        $left_time = $playerInfo['end_time'] - time();
        if ($playerInfo['get_coupons'] == 1 || $left_time <= 0) {
            $playerInfo['turn'] += 1;
        }
//        if ($playerInfo['turn'] > 3) {
//            $playerInfo['turn'] = 3;
//        }
        return $this->output(1, 'success', $playerInfo);
    }

    // 手动结束大奖赛游戏
    public function terminal()
    {
        $account = $this->request->post('account', '');
        $stage = $this->request->post('stage', '');
        if (empty($account) || empty($stage)) {
            return $this->output(400, '参数缺失');
        }
        $playerInfo = Djs::getDjsPlayerData($account);
        if (empty($playerInfo)) {
            return $this->output(400, 'OK', ['status' => '非法操作']);
        }
        $left_time = $playerInfo['end_time'] - $playerInfo['start_time'];
        if (($playerInfo['status'] == 1) && ($playerInfo['get_coupons'] == 0) && ($left_time > 0)) {
            return $this->output(400, '游戏状态正常，不可结束');
        }
        // 设置游戏结束状态
        $playerInfo['get_coupons'] = 1;
        Djs::updatePlayerData($account, $playerInfo);

        $return_data['stage'] = (int)$playerInfo['stage'];
        $return_data['turn'] = (int)$playerInfo['turn'];
        $return_data['status'] = (int)$playerInfo['status'];
        $return_data['start_time'] = (int)$playerInfo['start_time'];
        $return_data['alive'] = (int)$playerInfo['alive'];
        $return_data['is_over'] = 1;

        return $this->output(1, 'OK', $return_data);
    }

    // 领奖
    public function draw()
    {
        $account = $this->request->post('account');
        $stage = $this->request->post('stage');
        if (empty($account) || empty($stage)) {
            return $this->output(400, '参数缺失');
        }
        $playerInfo = Djs::getDjsPlayerData($account);
        if (empty($playerInfo)) {
            return $this->output(400, '玩家状态数据不存在');
        }
        if ($playerInfo['stage'] < $stage) {
            return $this->output(400, '非法领取阶段');
        }
        if ($playerInfo['get_coupons'] == 1) {
            return $this->output(400, '已领取过了');
        } else {
            $check_where = [
                ['uid', '=', $account],
                ['challenge_start', '=', $playerInfo['start_time']],
                ['challenge_times', '=', $playerInfo['turn']],
                ['get_stage', '=', $stage],
            ];
            $is_get = GrandMatchRecord::getRecordsNum($check_where);
            if (($is_get['code'] == 0) && ($is_get['data'] > 0)) {
                return $this->output(400, '已领取过了');
            }
        }

        // 查询奖励
        $prizes = GameLevel::getPrize($stage);
        if ($prizes['code']) {
            return $this->output(400, '奖励不存在');
        }
        $prizes = $prizes['data'];
        if (count($prizes) > 1) {
            $prize_key = roll_prize($prizes);
        } else {
            $prize_key = $prizes[0]['id'];
        }
        foreach ($prizes as $k => $v) {
            if ($v['id'] == $prize_key) {
                //var_dump('奖励id',$prize_key,'所有奖励',$prizes,'奖励',$v);
                $where = [
                    ['cpns_id', '=', $v['cpns_id']],
                    ['cpns_status', '=', '1']
                ];
                $data = [
                    'uid' => $account,
                    'cpns_id' => $v['cpns_id'],
                    'cpns_hash' => $v['cpns_hash'],
                    'cpns_prefix' => $v['cpns_prefix'],
                    'cpns_key' => $v['cpns_key'],
                    'cpns_expire' => $v['cpns_expire'],
                ];
                // 插入大奖赛对局数据
                $record = [
                    'uid' => $account,
                    'round' => $playerInfo['stage'],
                    'get_stage' => $stage,
                    'win_lose' => $playerInfo['status'],
                    'cpns_id' => $v['cpns_id'],
                    'challenge_times' => $playerInfo['turn'],
                    'status' => 1,
                    'count' => $v['show_pre'],
                    'challenge_start' => $playerInfo['start_time']
                ];

                Db::beginTransaction();
                $con = GrandMatchRecord::insertRecord($record);
                if ($con['code'] != 0) {
                    Db::rollBack();
                    return $this->output(400, $con['msg']);
                }

                // 发放奖励给玩家
                $res = MemberCoupon::assignCoupons($where, $data);
                if ($res['code'] != 0) {

                    Db::rollBack();
                    return $this->output(400, $res['msg']);
                }
                // 修改领取标记
                $playerInfo['get_coupons'] = 1;
                Djs::updatePlayerData($account, $playerInfo);
                $data1 = [
                    "level" => $v['level'],
                    "chance_per" => $v['chance_per'],
                    "show_pre" => $v['show_pre'],
                    "cpns_name" => $v['cpns_name'],
                    "cpns_expire" => $v['cpns_expire'],
                    "show_conditions" => $v['show_conditions'],
                    "cpns_code" => $res['data']['cpns_code']
                ];

                Db::commit();
                return $this->output(1, 'success', $data1);
            }
        }

    }

    public function rank()
    {
        $redis = redis();
        $game_conf = config('game');
        $robot_conf = config('robot');
        $account = $this->request->post('account');
        $rank_key = $game_conf['djs_rank'];
        if ($redis->exists($rank_key)) {
            $rankList = $redis->zRevRange($rank_key, 0, 99, true);
            $uid_arr = array_keys($rankList);
        } else {
            // 查询玩家真实券
            $where = [
                ['uid', '=', $account],
                ['count', '=', 0]
            ];
            $num = GrandMatchRecord::getRecordsNum($where);
            $score = 0;
            if ($num['code'] == 0) {
                $score = $num['data'];
            }
            $uid_arr[] = $account;
            $redis->zAdd($rank_key, (int)$score, (string)$account);
            $robot_keys = array_rand($robot_conf['robots'], 99);
            foreach ($robot_keys as $v) {
                $score = rand(10, 50);
                $redis->zAdd($rank_key, (int)$score, (string)$v);
                array_push($uid_arr, $v);
            }
            $rankList = $redis->zRevRange($rank_key, 0, 99, true);
        }

        $rank = $this->getUserRankInfo($rankList, $uid_arr);
        return $this->output(1, 'success', $rank);
    }

    private function getUserRankInfo($rankList, $uids)
    {
        $uinfo_arr = User::getUsers($uids);
        if ($uinfo_arr['code']) {
            return [];
        }
        foreach ($rankList as $k => $v) {
            foreach ($uinfo_arr['data'] as $ks => $vs) {
                if ($k == $vs['account']) {
                    $info[] = [
                        'account' => $k,
                        'nickname' => filterNickname($vs['nickname']),
                        'avatar' => $vs['avatar'],
                        'score' => $v
                    ];
                }
            }
        }
        return $info;
    }
}